// 云函数入口文件
const cloud = require('wx-server-sdk');
const request = require('request');
cloud.init();
const db = cloud.database();
const _ = db.command;
//演示的比赛数组
const demoContestSids = [1];

var random = function (radix) {
  var val = 9999;
  if (radix) {
    val = 1 << (radix * 4);
  }
  return parseInt((Math.random() * val).toFixed());
}

var rp = function (options) {
  return new Promise((resolve, reject) => {
    request(options, (error, response, body) => {
      if (error) {
        reject(error);
      }
      resolve(response);
    });
  });
};
var get = async function (url) {
  var result = await rp({
    url: url,
    method: 'GET'
  });
  var obj = (typeof result.body === 'object') ? result.body : JSON.parse(result.body);
  return obj;
}

var post = async function (url, body) {
  var result = await rp({
    url: url,
    method: 'POST',
    headers: {
      'content-type': 'application/json',
    },
    body: JSON.stringify(body)
  });
  var obj = (typeof result.body === 'object') ? result.body : JSON.parse(result.body);
  return obj;
}

var registerAndReturnUser = async function (event) {
  const wxContext = cloud.getWXContext();
  var info = {
    openid: wxContext.OPENID,
    appid: wxContext.APPID,
    unionid: wxContext.UNIONID,
    nickname: event.nickname
  };
  var countRet = await db.collection('user').where({
    openid: info.openid
  }).count();
  var count = countRet.total;
  if (count <= 0) {
    var res = await db.collection('config').where({
      key: 'userid'
    }).get();
    var nextId = 1;
    if (res.data && res.data.length > 0) {
      nextId = res.data[0].value;
      var configId = res.data[0]._id;
      await db.collection('config').doc(configId).update({
        data: {
          value: _.inc(1)
        }
      })
    }
    await db.collection('user').add({
      data: {
        sid: nextId,
        openid: info.openid,
        nickname: info.nickname,
        role: 'normal'
      }
    });
    return {
      sid: nextId,
      openid: info.openid,
      nickname: info.nickname,
      role: 'normal'
    };
  } else {
    var res = await db.collection('user').where({
      openid: info.openid
    }).get();
    if (res.data && res.data.length > 0) {
      var data = res.data[0];
      return {
        sid: data.sid,
        openid: data.openid,
        nickname: data.nickname,
        role: data.role
      };
    }
  }
  return {
    openid: info.openid,
    nickname: info.nickname,
    role: 'normal'
  };
};
var fetchUserList = async function (event) {
  var page = event.page || 1;
  var limit = event.limit || 10;
  var offset = (page - 1) * limit;
  var searchusername = event.searchusername;
  var ret;
  if (searchusername) {
    ret = await db.collection('user').where({
      nickname: db.RegExp({
        regexp: '.*' + searchusername + '.*',
        options: 'i',
      })
    }).orderBy('role', 'asc').orderBy('sid', 'asc').skip(offset).limit(limit).get();
  } else {
    ret = await db.collection('user').orderBy('role', 'asc').orderBy('sid', 'asc').skip(offset).limit(limit).get();
  }
  if (ret.data && ret.data.length) {
    return ret.data;
  }
  return null;
};
var updateUser = async function (event) {
  var userid = event.userid;
  var toRole = event.role;
  await db.collection('user').doc(userid).update({
    data: {
      role: toRole
    }
  });
  return;
};
var fetchContestList = async function (event) {
  const wxContext = cloud.getWXContext();
  var info = {
    openid: wxContext.OPENID,
    appid: wxContext.APPID,
    unionid: wxContext.UNIONID,
  };
  var page = event.page || 1;
  var limit = event.limit || 10;
  var offset = (page - 1) * limit;
  var sid = event.sid;
  var isguest =false;
  var userrole = event.userrole;
  var id = event.id;
  var area = event.area || 'user';
  if(!userrole){
    isguest = true;
  }
  var ret;
  if(id){
    ret = await db.collection('contest').where({
      _id: id
    }).get();
  } else if (sid) {
    //用sid精确查找比赛
    ret = await db.collection('contest').where({
      sid: sid
    }).get();
  } else {
    //返回能查到的比赛数组
    if(isguest){
      ret = await db.collection('contest').where({
        sid: _.in(demoContestSids)
      }).skip(offset).limit(limit).get();
    } else {
      //查询用户创建或者参与的比赛
      var sids = [];
      var userRet = await db.collection('user').where({
        openid: info.openid
      }).get();
      if(userRet.data && userRet.data.length){
        console.log('userret', JSON.stringify(userRet.data));
        var user = userRet.data[0];
        var contest_userRet;
        if(area === 'host'){
          //只查询用户主办的比赛
          contest_userRet = await db.collection('contest_user').where({
            userId: user.sid,
            role: 'creator'
          }).get();
        } else {
          contest_userRet = await db.collection('contest_user').where({
            userId: user.sid
          }).get();
        }
        if(contest_userRet.data && contest_userRet.data.length){
          console.log('contest_userRet', JSON.stringify(contest_userRet.data));
          contest_userRet.data.forEach(function(item){
            sids.push(item.contestId);
          });
        }
      }
      ret = await db.collection('contest').where({
        sid: _.in(sids)
      }).skip(offset).limit(limit).get();
    }
  }
  if (ret.data && ret.data.length) {
    return ret.data;
  }
  return null;
};
var fetchPlayerList = async function (event) {
  const wxContext = cloud.getWXContext();
  var info = {
    openid: wxContext.OPENID,
    appid: wxContext.APPID,
    unionid: wxContext.UNIONID,
  };
  var page = event.page || 1;
  var limit = event.limit || 10;
  var offset = (page - 1) * limit;
  var contestId = event.contestId;
  if(!contestId){
    return null;
  }
  var ret;
  ret = await db.collection('contest_player').where({
    contestId: contestId
  }).orderBy('score', 'desc').get();
  if (ret.data && ret.data.length) {
    return ret.data;
  }
  return null;
};
var saveContest = async function(event){
  const wxContext = cloud.getWXContext();
  var info = {
    openid: wxContext.OPENID,
    appid: wxContext.APPID,
    unionid: wxContext.UNIONID,
  };
  var id = event.id;
  var name = event.name;
  var host = event.host;
  var holdDate = event.holdDate;
  var state = event.state;
  var data = {};
  if(name){
    data.name = name;
  }
  if(host){
    data.host = host;
  }
  if(holdDate){
    data.holdDate = holdDate;
  }
  if(state){
    data.state = state;
  }
  if(event.screenjob){
    data.screenjob = event.screenjob;
  }
  if(!id){
    //新增
    data.state = data.state || 'open';
    data.name = data.name || 'Contest' + (new Date()).getTime();
    Date.holdDate = data.holdDate || (new Date());
    var res = await db.collection('config').where({
      key: 'contestsid'
    }).get();
    var nextId = 1;
    if(res.data && res.data.length > 0){
      nextId = res.data[0].value;
      var configId = res.data[0]._id;
      await db.collection('config').doc(configId).update({
        data: {
          value: _.inc(1)
        }
      })
    }
    data.sid = nextId;
    await db.collection('contest').add({
      data: data
    });
    //更新用户与比赛关系表
    var userRet = await db.collection('user').where({
      openid: info.openid
    }).get();
    if(userRet.data && userRet.data.length){
      console.log('userret', JSON.stringify(userRet.data));
      var user = userRet.data[0];
      await db.collection('contest_user').add({
        data: {
          userId: user.sid,
          contestId: nextId,
          role: 'creator'
        }
      });
    }
  } else {
    //更新
    await db.collection('contest').doc(id).update({
      data: data
    });
  }
  return;
};
//生成比赛的小程序码
var generateContestQR = async function(event){
  var sid = event.sid;
  if(!sid){
    return null;
  }
  //查询比赛
  var contestRet = await db.collection('contest').where({
    sid: parseInt(sid)
  }).get();
  if(contestRet.data && contestRet.data.length){
    var contest = contestRet.data[0];
    var ret = await cloud.openapi.wxacode.getUnlimited({
      scene: '1047',
      page: 'pages/index/index'
    });
    return ret;
  }
  return null;
}
// 云函数入口函数
exports.main = async (event, context) => {

  var action = event.action;
  if (!action) {
    return { code: 20000, msg: 'hello, world' };
  }
  //dispatcher
  var ret;
  if (action === 'role') {
    ret = await registerAndReturnUser(event);
  } else if (action === 'userlist') {
    ret = await fetchUserList(event);
  } else if (action === 'updaterole') {
    ret = await updateUser(event);
  } else if(action === 'contests'){
    ret = await fetchContestList(event);
  } else if(action === 'savecontest'){
    ret = await saveContest(event);
  } else if(action === 'players'){
    ret = await fetchPlayerList(event);
  } else if(action === 'generateContestQR'){
    ret = await generateContestQR(event);
  }

  if (typeof (ret) === 'undefined') {
    return { code: 20400, msg: 'nocontent' };
  } else if (ret === null) {
    return { code: 40400, msg: 'not found' };
  } else if (ret) {
    return { code: 20000, msg: 'success', data: ret };
  }

}